
import 'dart:io';

import 'package:carapacik_dio_logger/carapacik_dio_logger.dart';
import 'package:dio/dio.dart';
import 'package:dio/io.dart';
import 'package:dio_cache_interceptor/dio_cache_interceptor.dart';
import 'package:flutter/foundation.dart';
import 'package:gluz/app/utils/app_env.dart';
import 'package:http_cache_hive_store/http_cache_hive_store.dart';
import 'package:path_provider/path_provider.dart';
import 'package:pretty_dio_logger/pretty_dio_logger.dart';
import '../../../app_session.dart';
import 'interceptor/error_interceptor.dart';
import 'interceptor/request_interceptor.dart';

export 'package:dio/dio.dart';


class Http {
  static late final Dio dio;
  final CancelToken _cancelToken = CancelToken();
  late HiveCacheStore cacheStore;
  late CacheOptions cacheOptions;

  Dio get dioInstance => Http.dio;

  Options forceCacheOptions() {
    return cacheOptions.copyWith(policy: CachePolicy.forceCache).toOptions();
  }

  Future<void> setup() async {
    BaseOptions op = BaseOptions(
      baseUrl: app.env.javaUrl,
      connectTimeout: Duration(seconds: 10),
      receiveTimeout: Duration(seconds: 10),
      responseType: ResponseType.json,
      headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
      },
    );
    cacheOptions = CacheOptions(
      // A default store is required for interceptor.
      store: MemCacheStore(), // 先使用内存缓存, 如果想要是用磁盘缓存请使用上面的cacheStore替换

      // All subsequent fields are optional to get a standard behaviour.

      // Default.
      policy: CachePolicy.request,
      // Returns a cached response on error for given status codes.
      // Defaults to `[]`.
      hitCacheOnErrorCodes: const [500],
      // Allows to return a cached response on network errors (e.g. offline usage).
      // Defaults to `false`.
      hitCacheOnNetworkFailure: true,
      // Overrides any HTTP directive to delete entry past this duration.
      // Useful only when origin server has no cache config or custom behaviour is desired.
      // Defaults to `null`.
      maxStale: const Duration(days: 7),
      // Default. Allows 3 cache sets and ease cleanup.
      priority: CachePriority.high,
      // Default. Body and headers encryption with your own algorithm.
      cipher: null,
      // Default. Key builder to retrieve requests.
      keyBuilder: CacheOptions.defaultCacheKeyBuilder,
      // Default. Allows to cache POST requests.
      // Assigning a [keyBuilder] is strongly recommended when `true`.
      allowPostMethod: false,
    );

    dio = Dio(op);
    // 添加拦截器
    dio.interceptors.add(RequestInterceptor());
    dio.interceptors.add(ErrorInterceptor());
    dio.interceptors.add(DioCacheInterceptor(options: cacheOptions));
    // dio.interceptors.add(PrettyDioLogger(
    //   requestBody: true,
    //   enabled: kDebugMode,
    // ));
    dio.interceptors.add(
      const CarapacikDioLogger(
        error: true,
        request: true,
        requestHeader: true,
        requestQueryParameters: true,
        requestBody: true,
        response: true,
        responseHeader: true,
        responseBody: true,
        convertFormData: true,
        colorized: false,
        showCurl: false,
        chunkSize: 1024,
        logPrint: print,
        showLog: kDebugMode,
      ),
    );

    // (dio.httpClientAdapter as IOHttpClientAdapter).onHttpClientCreate = (client) {
    //   client.badCertificateCallback = (cert, host, port) {
    //     return true;
    //   };
    // };
    dio.httpClientAdapter = IOHttpClientAdapter(
      createHttpClient: () {
        final client = HttpClient();
        client.badCertificateCallback = (X509Certificate cert, String host, int port) => true;
        return client;
      },
    );
  }

  // Future getSystemProxy() async {
  //   if (Platform.isMacOS || Platform.isWindows || Platform.isLinux || Platform.isFuchsia) return;
  //   if (kReleaseMode) return;
  //   // 在调试模式下需要抓包调试，所以我们使用代理，并禁用HTTPS证书校验
  //   try {
  //     ProxySetting proxy = await NativeProxyReader.proxySetting;
  //     logger.w('系统代理：${proxy.host}:${proxy.port}');
  //     if (proxy.host == null || proxy.port == null) return;
  //     dio.httpClientAdapter = IOHttpClientAdapter(
  //       createHttpClient: () {
  //         final client = HttpClient();
  //         client.findProxy = (uri) {
  //           return "PROXY ${proxy.host}:${proxy.port}";
  //         };
  //         //代理工具会提供一个抓包的自签名证书，会通不过证书校验，所以我们禁用证书校验
  //         client.badCertificateCallback =
  //             (X509Certificate cert, String host, int port) => true;
  //         return client;
  //       }
  //     );
  //   } catch (e) {
  //     logger.e(e);
  //   }
  // }

  void cancelRequest({required CancelToken token}) {
    _cancelToken.cancel('手动取消请求');
  }

  Future<T> get<T>(String path,
      {Map<String, dynamic>? params,
      Options? options,
        String? contentType = Headers.formUrlEncodedContentType,
      CancelToken? cancelToken}) async {
    Options requestOptions = options?.copyWith(contentType: contentType) ??
        Options(
          contentType: contentType,
        );
    Response response = await dio.get<T>(
      path,
      queryParameters: params,
      options: requestOptions,
      cancelToken: cancelToken ?? _cancelToken,
    );
    return response.data;
  }

  Future<T> post<T>(String path,
      {Map<String, dynamic>? queryParams,
      dynamic data,
      Options? options,
      String? contentType = Headers.jsonContentType,
      CancelToken? cancelToken}) async {
    Options requestOptions = options?.copyWith(contentType: contentType,) ??
        Options(
          contentType: contentType,
        );
    Response response = await dio.post<T>(
      path,
      queryParameters: queryParams,
      data: data,
      options: requestOptions,
      cancelToken: cancelToken ?? _cancelToken,
    );
    return response.data;
  }
}
